package com.crm.system.controller.orderManager;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.crm.common.model.DataResponse;
import com.crm.common.model.DhPageInfo;
import com.crm.common.model.DhResponse;
import com.crm.common.model.Enum.ResponseCodeEnum;
import com.crm.common.util.DateUtil;
import com.crm.framework.listener.ExcelListener;
import com.crm.model.entity.sys.UserAccount;
import com.crm.model.qo.orderManager.ExportOrderProductQO;
import com.crm.model.qo.sys.ImportFailureLogQO;
import com.crm.model.vo.orderManager.CustomerProductOrderImportVO;
import com.crm.model.vo.orderManager.OrderProductPriceVO;
import com.crm.model.vo.sys.ImportFailureLogVO;
import com.crm.system.service.orderManager.CustomerProductOrderImportService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ Author ：pym
 * @ Date   ：2021/6/1 9:49
 */
@RestController
@RequestMapping("/customerProductOrderImport")
@Slf4j
public class CustomerProductOrderImportController {
    @Autowired
    CustomerProductOrderImportService customerProductOrderImportService;

    /**
     * 订单导入
     * @Author pym
     * @Date  2021/6/1 11:02
     * @param request
     * @param file 导入文件
     * @return {@link {com.crm.common.model.DataResponse}}
     */
    @PostMapping("/import")
    public DataResponse customerProductOrderImport(HttpServletRequest request, @RequestParam MultipartFile file) {
        try {
            ExcelListener excelDataListener = new ExcelListener();
            List<CustomerProductOrderImportVO> list = EasyExcel.read(file.getInputStream(), CustomerProductOrderImportVO.class,excelDataListener).sheet(0).doReadSync();
            if (list == null || list.size() == 0) {
                return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
            }
            JSONObject jsonObject = customerProductOrderImportService.importCustomerProductOrder(list);
            //返回导入数量、重复数量
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),jsonObject);
        } catch (Exception e) {
            log.error("customerProductOrderImport import error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 导入失败数据列表
     * @Author pym
     * @Date  2021/6/8 15:32
     * @param pageIndex -页码
     * @param pageSize -分页大小
     * @param sortName -排序列名字
     * @param sortOrder -排序规则(asc/desc)
     * @param importFailureLogQO -查询条件
     * @return {@link {com.crm.common.model.DataResponse}}
     */
    @PostMapping("/orderFailedDataList")
    public DataResponse orderFailedDataList(HttpServletRequest request,
                                             @RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                             @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                             @RequestParam(value="sortName",required = false) String sortName,//排序列名字
                                             @RequestParam(value="sortOrder",required = false) String sortOrder,//排序规则(asc/desc)
                                             ImportFailureLogQO importFailureLogQO//查询条件
    ){
        try{
            DhPageInfo<ImportFailureLogVO> importFailedDataList
                    = customerProductOrderImportService.selectOrderImportFailedDataList(pageIndex,pageSize,importFailureLogQO,sortName,sortOrder);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),importFailedDataList);
        }catch(Exception e){
            log.error("customerProductOrderImport orderFailedDataList error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 订单产品 月份报表统计
     * @Author pym
     * @Date  2021/8/13 10:29
     * @param response
     * @param request
     * @param exportOrderProductQO 筛选条件
     * @return {@link }
     */
    @GetMapping("/exportOrderProduct")
    public void exportOrderProduct(HttpServletResponse response, HttpServletRequest request,
                                   ExportOrderProductQO exportOrderProductQO//查询条件
                                   ) throws IOException {
        ExcelWriter excelWriter = null;
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码
            String fileName = URLEncoder.encode("订单产品 "+ DateUtil.getDate("yyyy-MM-dd HH_mm_ss"), "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
            excelWriter = EasyExcel.write(response.getOutputStream()).build();
            writeSheet(excelWriter, horizontalCellStyleStrategy, 0, "memberNew", "会员新建订单", exportOrderProductQO);
            writeSheet(excelWriter, horizontalCellStyleStrategy, 1, "membershipRenewal", "会员续费订单", exportOrderProductQO);
            writeSheet(excelWriter, horizontalCellStyleStrategy, 2, "course", "课程订单", exportOrderProductQO);
            writeSheet(excelWriter, horizontalCellStyleStrategy, 3, "refund", "退款", exportOrderProductQO);
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
            log.error("customerProductOrderImport exportOrder error:", e);
        } finally {
            //关闭流
            if(excelWriter != null){
                excelWriter.finish();
            }
        }
    }

    /**
     * 创建sheet并写入数据
     * @Author pym
     * @Date  2021/8/13 10:30
     * @param excelWriter
     * @param horizontalCellStyleStrategy
     * @param sheetNo
     * @param type 类型 memberNew：会员新建订单；membershipRenewal：会员续费订单；course：课程订单；refund：退款
     * @param sheetName
     * @param exportOrderProductQO 筛选条件
     * @return {@link }
     */
    private void writeSheet(ExcelWriter excelWriter, HorizontalCellStyleStrategy horizontalCellStyleStrategy,
                            Integer sheetNo, String type, String sheetName, ExportOrderProductQO exportOrderProductQO) {
        List<List<Object>> list = new ArrayList<>();
        List<List<String>> header = getHeaderAndData(list, type, exportOrderProductQO);
        //创建一个sheet
        WriteSheet writeSheet = EasyExcel.writerSheet(sheetNo, sheetName).head(header).registerWriteHandler(horizontalCellStyleStrategy).build();
        excelWriter.write(list, writeSheet);
    }

    /**
     * 设置样式和字体
     * @Author pym
     * @Date  2021/8/13 10:31
     * @param
     * @return {@link {com.alibaba.excel.write.style.HorizontalCellStyleStrategy}}
     */
    private HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 背景色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 12);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置内容靠左对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        // 字体策略
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short) 12);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        return horizontalCellStyleStrategy;
    }

    /**
     * 获取表头和数据
     * @Author pym
     * @Date  2021/8/13 10:32
     * @param dataList 数据
     * @param type 类型 memberNew：会员新建订单；membershipRenewal：会员续费订单；course：课程订单；refund：退款
     * @param exportOrderProductQO 筛选条件
     * @return {@link {java.util.List<java.util.List<java.lang.String>>}}
     */
    private List<List<String>> getHeaderAndData(List<List<Object>> dataList, String type, ExportOrderProductQO exportOrderProductQO) {
        List<List<String>> list = new ArrayList<List<String>>();
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//当前登录人信息
        if (userAccount != null) {
            String companyId = null;
            if (!"3".equals(userAccount.getDeptId())) {//分公司财务
                companyId = userAccount.getCompanyId();
            }
            List<String> productNameList = customerProductOrderImportService.getProductNameList(type, exportOrderProductQO, companyId);
            if (productNameList != null && productNameList.size() >0) {
                List<OrderProductPriceVO> productNameAndPriceList = customerProductOrderImportService.getProductNameAndPriceList(type, exportOrderProductQO, companyId);
                if (productNameAndPriceList != null && productNameAndPriceList.size() >0) {
                    Map<String, List<OrderProductPriceVO>> productNameAndPriceMap
                            = productNameAndPriceList.stream().collect(Collectors.groupingBy(productNameAndPrice -> productNameAndPrice.getCompanyName()));
                    List<String> head0 = new ArrayList<String>();
                    head0.add("行标签");
                    list.add(head0);
                    for (String productName : productNameList) {
                        List<String> head = new ArrayList<>();
                        head.add(productName);
                        list.add(head);
                    }
                    List<String> total = new ArrayList<String>();
                    if ("memberNew".equals(type)) {
                        total.add("新单合计");
                    } else if ("membershipRenewal".equals(type)) {
                        total.add("续费合计");
                    } else if ("course".equals(type)) {
                        total.add("单品合计");
                    } else if ("refund".equals(type)) {
                        total.add("退款合计");
                    }
                    list.add(total);
                    productNameAndPriceMap.forEach((k, v) -> {
                        BigDecimal totalPrice = new BigDecimal("0.00");
                        List<Object> data = new ArrayList<>();
                        String companyName = k;
                        data.add(companyName);
                        List<OrderProductPriceVO> ls = v;
                        for (String productName : productNameList) {
                            Boolean flag = true;
                            for (OrderProductPriceVO orderProductPrice : ls) {
                                if (productName.equals(orderProductPrice.getProductName())) {
                                    BigDecimal price = orderProductPrice.getPrice();
                                    data.add(price);
                                    totalPrice = totalPrice.add(price);
                                    flag = false;
                                }
                            }
                            if (flag) {
                                data.add("");
                            }
                        }
                        data.add(totalPrice);
                        dataList.add(data);
                    });
                }
            }
        }
        return list;
    }

}
